﻿using System;
using System.Collections.Generic;
using System.Data.SQLite;
using System.Linq;
using System.Text;
using LogHelper.SQLiteORM.Attributes;
using System.Reflection;

namespace LogHelper.SQLiteORM.Internal
{
    internal static class SqLiteExtensions
    {
        internal static string GetNameOrDefault(this Type type, Type attribute, string @default)
        {
            var attributes = type.GetCustomAttributes(attribute, true);
            if (!attributes.Any() || !(attributes[0] is NamedAttribute))
                return @default;
            var name = ((NamedAttribute)attributes[0]).Name;
            return !string.IsNullOrEmpty(name) ? name : @default;
        }

        internal static bool IsAutoIncrement(this MemberInfo info)
        {
            var customAttributes = info.GetCustomAttributes(typeof(PrimaryKeyAttribute), true);
            if (!customAttributes.Any())
                return false;
            var attribute = (PrimaryKeyAttribute)customAttributes[0];
            return attribute.IsPrimary && attribute.IsAutoIncrement;
        }

        internal static ColumnDescriptor GetColumnDescriptor(this MemberInfo member)
        {
            var attributes = member.GetCustomAttributes(typeof(ColumnAttribute), true) as ColumnAttribute[];
            if (attributes == null || !attributes.Any())//该字段未标记列特性或者不存在列特性，忽略映射
                return null;
            var attribute = attributes[0];
            return new ColumnDescriptor
            {
                IsPrimary = attribute.IsPrimary,
                Name = string.IsNullOrEmpty(attribute.Name) ? member.Name : attribute.Name,
                Type = attribute.Type,
                AllowNull = attribute.AllowNull,
                IsAutoIncrement = member.IsAutoIncrement(),
                Default = attribute.Default
            };
        }

        internal static object GetColumnOrDefault<TEntity>(this PropertyInfo info, TEntity entity)
        {
            return info.GetValue(entity, null);
        }

        internal static bool IsIgnore(this PropertyInfo info)
        {
            return info.GetCustomAttributes(typeof(IgnoreAttribute), true).Any();
        }

        internal static string GetTableName(this Type type)
        {
            return type.GetNameOrDefault(typeof(TableAttribute), type.Name);
        }

        internal static string CreateSql(this Type model, Func<PropertyInfo, string, string> action = null)
        {
            var table = model.GetTableName();

            var builder = new StringBuilder();
            builder.Append("Create Table If Not Exists ");
            builder.Append(table);
            builder.Append(" (");

            foreach (var property in model.GetProperties())
            {
                var descriptor = GetColumnDescriptor(property);
                if (descriptor == null) //该属性未标记ColumnAttribute特性
                    continue;

                if (descriptor.IsPrimary && descriptor.AllowNull)
                    throw new Exception("主键不能设置为可空类型");

                var column = descriptor.GetNameOrDefault(property.Name);
                builder.Append(column);
                builder.Append(" ");
                builder.Append(action == null ? descriptor.Type : action(property, descriptor.Type)); //负责C#和SqLite数据类型的映射
                builder.Append(descriptor.IsPrimary ? " Primary Key " : " ");//判断是否是主键
                builder.Append(descriptor.IsAutoIncrement ? " AUTOINCREMENT " : " ");
                builder.Append(descriptor.AllowNull ? " " : " Not Null "); //判断是否允许为空
                builder.Append(",");
            }
            return builder.RemoveTail().Append(")").ToString();
        }

        internal static string InsertSql(this object instance, IList<SQLiteParameter> paramsValue)
        {
            try
            {
                var model = instance.GetType();
                var table = model.GetTableName();

                var builder = new StringBuilder();
                var paramters = new StringBuilder();
                builder.Append("Insert Into ");
                builder.Append(table);
                builder.Append(" (");

                foreach (var property in model.GetProperties())
                {
                    if (property.IsIgnore() || property.IsAutoIncrement())
                        continue;

                    //Column1,Column2,Column3,
                    var name = property.GetColumnDescriptor().Name;

                    builder.Append(name);
                    builder.Append(",");

                    //最终形式@Column1,@Column2,@Column3,
                    paramters.Append("@");
                    paramters.Append(name);
                    paramters.Append(",");

                    //构建参数
                    paramsValue.Add(new SQLiteParameter("@" + name, property.GetColumnOrDefault(instance)));

                }
                
                return builder.RemoveTail().Append(") Values (").Append(paramters.RemoveTail()).Append(")").ToString();
            }
            catch(Exception ex) {
                Console.WriteLine(ex);
                return "";
            }
            

        }
        


    }
}